package com.faxsun.core.catalog.domain;

import java.util.*;

import javax.annotation.Resource;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.broadleafcommerce.common.extensibility.jpa.clone.ClonePolicy;
import org.broadleafcommerce.common.file.service.StaticAssetPathService;
import org.broadleafcommerce.common.media.domain.Media;
import org.broadleafcommerce.common.presentation.AdminPresentation;
import org.broadleafcommerce.common.presentation.AdminPresentationClass;
import org.broadleafcommerce.common.presentation.PopulateToOneFieldsEnum;
import org.broadleafcommerce.common.presentation.RequiredOverride;
import org.broadleafcommerce.common.presentation.client.SupportedFieldType;
import org.broadleafcommerce.common.util.BLCSystemProperty;
import org.broadleafcommerce.common.util.DateUtil;
import org.broadleafcommerce.common.web.BroadleafRequestContext;
import org.broadleafcommerce.core.catalog.domain.ProductAttribute;
import org.broadleafcommerce.core.catalog.domain.ProductImpl;
import org.broadleafcommerce.core.catalog.domain.RelatedProduct;
import org.broadleafcommerce.core.catalog.domain.Sku;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.SQLDelete;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@javax.persistence.Table(name = "FS_BLC_PRODUCT")
@SQLDelete(sql = "UPDATE FS_BLC_PRODUCT SET DEFAULT_SKU_ID = NULL WHERE PRODUCT_ID = ?")
@AdminPresentationClass(populateToOneFields = PopulateToOneFieldsEnum.TRUE, friendlyName = "FSProduct", ceilingDisplayEntity = "org.broadleafcommerce.core.catalog.domain.Product")
public class FSProductImpl extends ProductImpl {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @Column(name = "COUNTRY", nullable = false)
    @AdminPresentation(friendlyName = "ProductImpl_Product_Country", order = Presentation.FieldOrder.MANUFACTURER, group = Presentation.Group.Name.General, groupOrder = Presentation.Group.Order.General, fieldType = SupportedFieldType.BROADLEAF_ENUMERATION, broadleafEnumeration = "com.faxsun.core.catalog.domain.CountryEnum")
    protected String country;

    @Column(name = "SOURCE")
    @AdminPresentation(friendlyName = "ProductImpl_Product_Soruce", order = Presentation.FieldOrder.MANUFACTURER, group = Presentation.Group.Name.General, groupOrder = Presentation.Group.Order.General)
    protected String source;

    @Column(name = "SOURCEURL")
    @AdminPresentation(friendlyName = "ProductImpl_Product_SoruceURL", order = Presentation.FieldOrder.MANUFACTURER, group = Presentation.Group.Name.General, groupOrder = Presentation.Group.Order.General)
    protected String sourceURL;

    @Column(name = "ISBROAD")
    @AdminPresentation(friendlyName = "ProductImpl_Product_IsBroad", order = 1100, group = Presentation.Group.Name.General, groupOrder = Presentation.Group.Order.General, requiredOverride = RequiredOverride.REQUIRED)
    protected Boolean isBroad;

    @OneToOne(targetEntity = FSSkuImpl.class, cascade = {CascadeType.ALL})
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "blProducts")
    @Cascade(value = {org.hibernate.annotations.CascadeType.ALL})
    @JoinColumn(name = "DEFAULT_SKU_ID")
    @ClonePolicy(toOneProperty = "defaultProduct")
    protected Sku defaultSku;

    @Column(name = "BADGES", nullable = true)
    @AdminPresentation(friendlyName = "ProductImpl_Badges", requiredOverride = RequiredOverride.NOT_REQUIRED, tab = Presentation.Tab.Name.Marketing, tabOrder = Presentation.Tab.Order.Marketing, group = Presentation.Group.Name.Badges, groupOrder = Presentation.Group.Order.Badges, fieldType = SupportedFieldType.BROADLEAF_ENUMERATION, broadleafEnumeration = "com.faxsun.core.catalog.domain.FSBadgesEnum")
    protected String badges;

    @Transient
    protected Map<String, List<RelatedProduct>> relatedProductGroups;

    public CountryEnum getCountry() {
        return CountryEnum.getInstance(country);
    }

    public void setCountry(CountryEnum country) {
        this.country = country.getType();
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getSourceURL() {
        return sourceURL;
    }

    public void setSourceURL(String sourceURL) {
        this.sourceURL = sourceURL;
    }

    public Boolean getIsBroad() {
        return isBroad;
    }

    public void setIsBroad(Boolean isBroad) {
        this.isBroad = isBroad;
    }

    @Override
    public void setDefaultSku(Sku defaultSku) {
        if (defaultSku != null) {
            defaultSku.setDefaultProduct(this);

        }
        this.defaultSku = defaultSku;
    }

    @Override
    public Sku getDefaultSku() {
        return defaultSku;
    }

    public String getBadges() {
        return badges;
    }

    public void setBadges(String badges) {
        this.badges = badges;
    }

    public String getWinnerNumber() {
        ProductAttribute number = this.productAttributes.get("中奖号");
        return number == null ? "" : number.getValue();
    }

    public String getWinnerCustomerId() {
        ProductAttribute winner = this.productAttributes.get("中奖者");
        return winner == null ? "" : winner.getValue();
    }

    public boolean isCrossSaleProducts() {
        return this.crossSaleProducts.size() > 0;
    }

    @Override
    public Date getActiveStartDate() {
        return getDefaultSku() != null ? getDefaultSku().getActiveStartDate() : null;
    }

    @Override
    public Date getActiveEndDate() {
        return getDefaultSku() != null ? getDefaultSku().getActiveEndDate() : null;
    }

    public Map<String, List<RelatedProduct>> getRelatedProductGroups(List<RelatedProduct> relatedProducts) {
        if (relatedProductGroups == null) {
            relatedProductGroups = new HashMap<String, List<RelatedProduct>>();

            for (RelatedProduct relatedProduct : relatedProducts) {
                if (!relatedProductGroups.containsKey(relatedProduct.getPromotionMessage())) {
                    relatedProductGroups.put(relatedProduct.getPromotionMessage(),
                        new ArrayList<RelatedProduct>());
                }
                relatedProductGroups.get(relatedProduct.getPromotionMessage()).add(relatedProduct);
            }
        }
        return relatedProductGroups;
    }

    public Map<String, Media> getSortedMedia() {
        Map<String, Media> sortedMedia = new TreeMap<String, Media>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if (o1.equals("primary"))
                    return -1;
                if (o2.equals("primary"))
                    return 1;
                return o1.compareTo(o2);
            }
        });
        sortedMedia.putAll(super.getMedia());
        return sortedMedia;
    }

}